package com.eques.demo.anim

import android.annotation.SuppressLint
import android.content.Intent
import android.graphics.*
import android.graphics.drawable.AnimationDrawable
import android.graphics.drawable.Drawable
import android.media.AudioManager
import android.net.Uri
import android.os.Bundle
import android.os.Handler
import android.os.Looper
import android.os.Message
import android.provider.MediaStore
import android.text.TextUtils
import android.util.Log
import android.view.*
import android.widget.FrameLayout
import android.widget.ImageView
import android.widget.LinearLayout
import android.widget.RelativeLayout
import android.widget.RelativeLayout.LayoutParams
import android.widget.TextView
import android.widget.Toast
import androidx.constraintlayout.widget.ConstraintLayout
import com.eques.base.BaseActivity
import com.eques.bean.Mjpeg
import com.eques.database.DevList
import com.eques.database.dao.DevListDao
import com.eques.demo.R
import com.eques.event.EventTotalThread
import com.eques.icvss.core.module.user.BuddyType
import com.eques.icvss.utils.ELog
import com.eques.impl.ImgDataListener
import com.eques.service.DoorBellService
import com.eques.util.ActionUtils
import com.eques.util.BaseAppApplication
import com.eques.util.BitmapUtils
import com.eques.util.Config
import com.eques.util.FileHelper
import com.eques.util.ObjIsEmptyUtils
import com.eques.util.ScreenUtils
import com.eques.view.PopUtils
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.launch
import org.apache.commons.lang3.StringUtils
import org.greenrobot.eventbus.EventBus
import org.greenrobot.eventbus.Subscribe
import org.greenrobot.eventbus.ThreadMode
import java.io.File
import java.lang.ref.WeakReference
import java.util.*
import java.util.concurrent.Executors

/**
 * 宠物设备主页
 * @author yechen
 */
@Suppress("DEPRECATION")
class AnimalActivity : BaseActivity(),
    SurfaceHolder.Callback, ImgDataListener {
    private var tvMainLeftTopHint: TextView? = null
    private var tvMainTitleHint: TextView? = null
    private var ivMainRightTopHint: ImageView? = null
    private var constraintParent: RelativeLayout? = null
    private var surfaceviewVideo: TextureView? = null
    private var surfaceview: SurfaceView? = null
    private var rlMainHeadParent: ConstraintLayout? = null
    private var relParent: LinearLayout? = null
    private var tvLoading: TextView? = null
    private var linLoading: LinearLayout? = null
    private var linAnimalGroup: LinearLayout? = null
    private var tvAnimalMute: TextView? = null
    private var tvAnimalVoice: TextView? = null
    private var rel_failed_video: LinearLayout? = null
    private var img_back_logo: ImageView? = null
    private var img_play: ImageView? = null
    private var img_offline: ImageView? = null
    private var lin_video_parent: RelativeLayout? = null
    private var tv_animal_catch: TextView? = null
    private var tv_animal_video: TextView? = null
    private var tv_animal_send_food: TextView? = null
    private var tv_animal_clock: TextView? = null
    private var gf_videoLoadingGif: ImageView? = null
    private var tv_rec_time: TextView? = null
    private var tv_get_fail_remind: TextView? = null
    private var tv_animal_rec: TextView? = null
    private var tv_animal_alarm: TextView? = null
    private var popUtils: PopUtils? = null//用于喂食
    private var channelId = -1//用户保存视频channelId 用于呼叫
    private var isHasCall = false // 是否已经呼叫 防止重复呼叫
    private var devId: String? = null //设备ID
    private var uid: String? = null //当前用户ID,用于呼叫
    private var devType: Int? = null //设备类型
    private var devNick: String? = null//设备昵称
    private val camera_width = 640 //视频呼叫宽
    private val camera_height = 480 //视频呼叫高
    private var surfaceThread: SurfaceThread? = null //视频绘制线程
    private var mjpeg: Mjpeg? = null //用于临时存储视频数据
    private var isCatchBitmap = false //是否抓拍
    private var isStartRec = false //是否开始录像
    private var isPause = false //页面是否已经暂停
    private var captureVideoPath: String = "" //抓拍视频路径
    private var savePath: String = "" //保存路径
    private var isCreateOk: Boolean = false // 路径创建成功
    private var isClick = false // 是否点击
    private var screenWidthDip = 0 //屏幕宽 用于根据视频比例铺满屏幕
    private var screenHeightDip = 0 //屏幕高 用于根据视频比例铺满屏幕
    private var cameraId = 0 // 摄像头ID,来源于设备，需要根据此参数动态旋转画面
    private var videoWidth = 0f
    private var videoHeight = 0f
    private val TIME_CALL_CLOSE = 2000 //退出视频时长
    private var audioManager: AudioManager? = null
    private var current = 0
    private var percent = 0
    private val SAVE_PIC_TO_LOCAL: Int = 10
    private val FIRST_FRAME_COME = 11 //是否是第一帧动画
    private val LOADING = 12
    private var DISMISS_DIALOG = 13
    private var HANDLER_PIC_OK = 14
    private val REQUEST_AWAKEN = 15 // 唤醒设备
    private val LOADING_TIME_OUT = 16
    private val LOADING_DELAY_VIDEO = 17
    private val HANDLER_MSG_CLOSE_CALL = 18 //挂断视频
    private var HANDLER_REC_VIDEO_TIME = 19 //录制视频
    private var HANDLER_LONG_VIDEO_TIME = 20 //录制视频
    private val SAVE_PIC_TO_VIDEO_LOCAL: Int = 21
    private var init = true
    private var videoIsPlaying = false // //视频是否有第一帧画面，true：有,false:没有
    private lateinit var userName: String
    private var isRecordAudio = false//是否录制音频
    private var isPlayAudio = false//是否播放音频
    private var devState = 0//设备是否在线
    private var isShare = 0//是否是分享用户
    private var isCreateSuccess = false//SurfaceHolder创建成功
    private var isStartThread = false
    private var isSupport264 = false
    private var isClickSendFood = false
    private var sendValue = 1
    private var wakeupCount = 0 // 唤醒轮询次数，最多200次
    private var recTime = 0
    private var power_mode = 1
    private var path: String = ""
    private var leaveState = false//离开页面时候状态
    private lateinit var ykDao: DevListDao
    private val mHandler = MyHandler(WeakReference(this))

    private var devBean: DevList? = null

    inner class MyHandler(val wrActivity: WeakReference<AnimalActivity>) :
        Handler(Looper.getMainLooper()) {
        /**
         * 处理消息队列中的消息
         * @param msg 消息对象，包含消息类型和消息数据
         */
        override fun handleMessage(msg: Message) {
            super.handleMessage(msg)
            val activity = wrActivity.get()
            when (msg.what) {
                // 处理长视频时间消息
                HANDLER_LONG_VIDEO_TIME -> {
                    activity!!.closeAll(true, 3)
                }

                // 处理录制视频时间消息
                HANDLER_REC_VIDEO_TIME -> {
                    recTime++
                    tv_rec_time?.text = equesMytool!!.convertSecondsToTime(recTime)
                    if (recTime == 61) {
                        stopRec(false)
                    } else {
                        sendEmptyMessageDelayed(HANDLER_REC_VIDEO_TIME, 1000)
                    }
                }

                // 处理加载延迟视频消息
                LOADING_DELAY_VIDEO -> {
                    getBuddyInfo()
                    if (!ObjIsEmptyUtils.isEmpty(devBean)) {
                        devState = devBean!!.stat
                        if (devState == Config.DEVICE_ONLINE) {
                            call()
                        } else if (devState == Config.DEVICE_SLEEP) {
                            wakeUp()
                        } else {
                            deviceOffline()
                        }
                    } else {
                        deviceOffline()
                    }
                }

                // 处理关闭通话消息
                HANDLER_MSG_CLOSE_CALL -> {
                    stopProgressDialog()
                    activity!!.finish()
                }

                // 处理图片保存成功消息
                HANDLER_PIC_OK -> {
                    val picPath = msg.obj as String
                    val file = File(picPath)
                    if (file.exists()) {
                        stopProgressDialog()
                        removeMessages(this@AnimalActivity.HANDLER_PIC_OK)
                        val bitmap = BitmapUtils.getDiskBitmap(picPath)
                        if (bitmap != null) {
                            MediaStore.Images.Media.insertImage(
                                activity!!.contentResolver, bitmap, file.name, null
                            )
                            val intent = Intent(Intent.ACTION_MEDIA_SCANNER_SCAN_FILE)
                            val uri = Uri.fromFile(file)
                            intent.setData(uri)
                            intent.setPackage(packageName)
                            activity.sendBroadcast(intent)
                            ELog.showToastShort(activity, R.string.save_file_album_hint)
                        }
                        file.delete()
                    } else {
                        val message = Message()
                        message.obj = picPath
                        message.what = this@AnimalActivity.HANDLER_PIC_OK
                        sendMessageDelayed(message, (2 * 1000).toLong())
                    }
                }

                // 处理dismiss对话框消息
                DISMISS_DIALOG -> {
                    stopProgressDialog()
                }

                // 处理保存视频到本地消息
                SAVE_PIC_TO_VIDEO_LOCAL -> {
                    stopProgressDialog()
                    ELog.e("FileHelper", "save save $path")
                    FileHelper.copyVideoToAlbum(
                        this@AnimalActivity, savePath
                    )
                    ELog.showToast(
                        activity,
                        activity!!.getString(R.string.save_file_album_hint),
                        Toast.LENGTH_SHORT
                    )
                }

                // 处理保存图片到本地消息
                SAVE_PIC_TO_LOCAL -> {
                    stopProgressDialog()
                    ELog.showToast(
                        activity,
                        activity!!.getString(R.string.save_file_album_hint),
                        Toast.LENGTH_SHORT
                    )
                }

                // 处理接收到第一帧视频消息
                FIRST_FRAME_COME -> {
                    activity?.videoPlayUI()
                }

                // 处理加载中消息
                LOADING -> {
                    val random = Random()
                    activity?.percent = activity?.percent!! + random.nextInt(8) % (8 - 1 + 1) + 1
                    activity?.setPercent()
                    sendEmptyMessageDelayed(LOADING, 1000)
                }

                // 处理加载超时消息
                LOADING_TIME_OUT -> {
                    activity!!.rel_failed_video!!.visibility = View.VISIBLE
                }

                // 处理请求唤醒设备消息
                REQUEST_AWAKEN -> {
                    if (activity?.wakeupCount!! <= 60) {
                        DoorBellService.icvss!!.equesT1WakeUpScreen(activity.devId, 2, 1)
                        sendEmptyMessageDelayed(REQUEST_AWAKEN, 500)
                        activity.wakeupCount++
                    } else {
                        activity.mHandler.removeMessages(REQUEST_AWAKEN)
                    }
                }
            }
        }
    }

    /**
     * 用于创建视频画面
     */
    /**
     * 用于创建视频画面
     */
    fun videoPlayUI() {
        // 停止并释放现有的动画资源
        if (!ObjIsEmptyUtils.isEmpty(animationDrawable)) {
            animationDrawable!!.stop()
            animationDrawable = null
        }
        // 隐藏视频播放失败的界面
        rel_failed_video!!.visibility = View.GONE
        // 移除加载超时的消息
        mHandler.removeMessages(LOADING_TIME_OUT)
        // 隐藏加载中的界面
        linLoading?.visibility = View.GONE
        // 隐藏播放按钮
        img_play?.visibility = View.GONE
        // 隐藏返回按钮
        img_back_logo?.visibility = View.GONE
        // 隐藏离线状态图标
        img_offline?.visibility = View.GONE
        // 设置视频播放状态为true
        videoIsPlaying = true
        // 显示动画资源组
        linAnimalGroup?.visibility = View.VISIBLE
        // 设置按钮为灰色状态
        setButtonGray(true)

        // 启用或禁用音频播放功能
        DoorBellService.icvss!!.iot.audioPlayEnable(isPlayAudio)
        // 启用或禁用音频录制功能
        DoorBellService.icvss!!.iot.audioRecordEnable(isRecordAudio)
    }


    /**
     * 用户按钮点击
     */
    @SuppressLint("UseCompatLoadingForDrawables")
    fun viewClick(view: View) {
        when (view.id) {

            //进入喂食消息界面
            R.id.tv_animal_rec -> {
                val intent = Intent(ActionUtils.ACTION_COMMON_ANIMAL_MSG_ACTIVITY)
                intent.putExtra(Config.BID, devId)
                intent.setPackage(packageName)
                intent.putExtra(Config.TYPE, devType)
                startActivity(intent)
            }

            //进入喂食报警消息界面
            R.id.tv_animal_alarm -> {
                val intent = Intent(ActionUtils.ACTION_COMMON_ANIMAL_ALARM_ACTIVITY)
                intent.putExtra(Config.BID, devId)
                intent.setPackage(packageName)
                intent.putExtra(Config.TYPE, devType)
                startActivity(intent)
            }

            //设置定时
            R.id.tv_animal_clock -> {
                val clockIntent = Intent(ActionUtils.ACTION_COMMON_ANIMAL_CLOCK_ACTIVITY)
                clockIntent.putExtra(Config.BID, devId)
                intent.setPackage(packageName)
                clockIntent.putExtra("devType", devType)
                startActivity(clockIntent)
            }

            //视频查看失败，或超过时限，重新查看
            R.id.img_again -> {
                percent = 0
                isClick = true
                isHasCall = false
                img_play?.visibility = View.GONE
                rel_failed_video?.visibility = View.GONE
                call(3)
            }

            //点击查看视频
            R.id.img_play -> {
                percent = 0
                isClick = true
                isHasCall = false
                img_play?.visibility = View.GONE
                rel_failed_video?.visibility = View.GONE
                call(3)
            }

            //开始录制视频
            R.id.tv_animal_video -> {
                start()
            }

            //抓拍图片
            R.id.tv_animal_catch -> {
                isCatchBitmap = true
            }

            //是否静音
            R.id.tv_animal_mute -> {
                isPlayAudio = !isPlayAudio
                DoorBellService.icvss!!.iot.audioPlayEnable(isPlayAudio)
                var drawableWs: Drawable
                if (isPlayAudio) {
                    drawableWs = resources.getDrawable(R.mipmap.animal_muteoff)
                    drawableWs.setBounds(0, 0, drawableWs.minimumWidth, drawableWs.minimumHeight)
                } else {
                    drawableWs = resources.getDrawable(R.mipmap.animal_muteon)
                    drawableWs.setBounds(0, 0, drawableWs.minimumWidth, drawableWs.minimumHeight)
                }
                tvAnimalMute?.setCompoundDrawables(null, drawableWs, null, null)
            }

            //是否开启MIC
            R.id.tv_animal_voice -> {
                isRecordAudio = !isRecordAudio
                DoorBellService.icvss!!.iot.audioRecordEnable(isRecordAudio)
                setChoose()
            }

            //喂食
            R.id.tv_animal_send_food -> {
                sendValue = 1
                popUtils!!.setView(constraintParent).setOutsideTouchable(true).setFoodType(1)
                    .initShowPop(PopUtils.SEND_FOOD)
            }

        }
    }


    /**
     * 录制视频
     */
    @SuppressLint("UseCompatLoadingForDrawables")
    fun start() {
        // 检查是否已经创建好录制环境
        if (isCreateOk) {
            // 检查是否已经开始录制
            if (!isStartRec) {
                isStartRec = true
                recTime = 0
                tv_rec_time?.visibility = View.VISIBLE
                // 获取录制视频的图标
                val drawable = resources.getDrawable(R.mipmap.video_touch_rec)
                drawable.setBounds(0, 0, drawable.minimumWidth, drawable.minimumHeight)
                // 发送消息更新录制视频的时间
                mHandler.sendEmptyMessage(HANDLER_REC_VIDEO_TIME)
                // 延迟发送消息以限制视频录制的最长时间
                mHandler.sendEmptyMessageDelayed(HANDLER_LONG_VIDEO_TIME, 120 * 1000)
                // 生成视频文件的保存路径
                savePath = captureVideoPath + System.currentTimeMillis() + ".mp4"
                // 调用服务开始录制视频
                DoorBellService.icvss!!.iot.recordMp4(
                    savePath, 640, 480, equesMytool!!.getDegree264(cameraId)
                )
                // 设置录制视频的图标
                tv_animal_video?.setCompoundDrawables(null, drawable, null, null)
            } else {
                // 如果已经开始录制，则停止录制
                stopRec(false)
            }

        } else {
            // 如果录制环境未创建好，显示提示信息
            Toast.makeText(this, "敬请期待", Toast.LENGTH_SHORT).show()
        }
    }


    /**
     * 停止录制
     *
     * 此方法用于停止正在进行的视频录制，会根据录制状态更新UI和执行停止录制的操作
     * 如果close参数为false，还会显示进度对话框并保存最后一张图片到视频本地
     *
     * @param close 布尔值，指示是否关闭录制界面，true表示直接关闭，false表示显示进度对话框
     */
    @SuppressLint("UseCompatLoadingForDrawables")
    fun stopRec(close: Boolean) {
        // 检查是否正在录制
        if (isStartRec) {
            // 更新录制状态为停止
            isStartRec = false
            // 记录日志
            ELog.e("FileHelper", "stop start $path")
            // 调用服务停止录制
            DoorBellService.icvss!!.iot.stopRecordMp4()
            // 隐藏录制时间视图
            tv_rec_time?.visibility = View.GONE
            // 获取并设置停止录制图标
            var drawable = resources.getDrawable(R.mipmap.animal_phone_off)
            drawable.setBounds(0, 0, drawable.minimumWidth, drawable.minimumHeight)
            // 移除录制时间更新消息
            mHandler.removeMessages(HANDLER_REC_VIDEO_TIME)
            // 根据close参数决定是否显示进度对话框
            if (!close) {
                createProgressDialog(this, Config.PROGRESS_ERROR_CODE, false);
            }
            // 更新视图的绘制图标
            tv_animal_video?.setCompoundDrawables(null, drawable, null, null)
            // 发送延迟消息保存图片到视频本地
            mHandler.sendEmptyMessageDelayed(SAVE_PIC_TO_VIDEO_LOCAL, 5 * 1000)
        }
    }

    /**
     * 改变MIC的状态
     */
    @SuppressLint("UseCompatLoadingForDrawables")
    fun setChoose() {
        var drawableWs2: Drawable
        if (isRecordAudio) {
            drawableWs2 = resources.getDrawable(R.mipmap.animal_voice_touch)
            drawableWs2.setBounds(0, 0, drawableWs2.minimumWidth, drawableWs2.minimumHeight)
            tvAnimalVoice?.setCompoundDrawables(null, drawableWs2, null, null)
        } else {
            drawableWs2 = resources.getDrawable(R.mipmap.animal_voice)
            drawableWs2.setBounds(0, 0, drawableWs2.minimumWidth, drawableWs2.minimumHeight)
            tvAnimalVoice?.setCompoundDrawables(null, drawableWs2, null, null)
        }
    }

    /**
     * 创建本地抓拍路径
     *
     * 此方法旨在确保用于存储抓拍视频的本地路径存在如果路径不存在，它将尝试创建该路径
     * 它依赖于equesMytool工具类来生成初始路径，并使用FileHelper类来检查路径是否存在以及创建新目录
     *
     * @return 返回一个布尔值，指示目录是否已成功存在或创建
     */
    private fun checkCapturePathIsExist(): Boolean {
        var bo = true
        // 日志输出，用于调试和记录当前的工具类和设备ID状态
        ELog.e("capturePath", "$equesMytool ")
        ELog.e("capturePath", "$devId ")

        // 创建本地抓拍路径，包括活动上下文、设备ID、捕获文件夹名称和自定义文件名前缀
        captureVideoPath = equesMytool!!.captureLocalMp4Path(
            this@AnimalActivity,
            devId!!,
            equesMytool!!.createCaptureFolderName()!!,
            "anim_$userName"
        )!!

        // 检查生成的捕获路径是否存在
        val fileIsExist = FileHelper.fileIsExist(captureVideoPath)
        if (!fileIsExist) {
            // 如果路径不存在，尝试创建新目录
            bo = FileHelper.createDirectory(captureVideoPath)
        }

        // 日志输出，记录本地视频存储路径
        ELog.e("capturePath", "$captureVideoPath 本地视频存储路径")
        return bo
    }


    override fun initView() {
        rel_failed_video = findViewById(R.id.rel_failed_video)
        tvMainLeftTopHint = findViewById(R.id.tv_main_left_top_hint)
        tvMainTitleHint = findViewById(R.id.tv_main_title_hint)
        ivMainRightTopHint = findViewById(R.id.iv_main_right_top_hint)
        constraintParent = findViewById(R.id.constraint_parent)
        surfaceview = findViewById(R.id.surfaceview)
        surfaceviewVideo = findViewById(R.id.surfaceview_video)
        rlMainHeadParent = findViewById(R.id.rl_main_head_parent)
        tv_animal_send_food = findViewById(R.id.tv_animal_send_food)
        tv_animal_clock = findViewById(R.id.tv_animal_clock)
        relParent = findViewById(R.id.rel_parent)
        gf_videoLoadingGif = findViewById(R.id.gf_videoLoadingGif)
        tvLoading = findViewById(R.id.tv_loading)
        linLoading = findViewById(R.id.lin_loading)
        tv_animal_rec = findViewById(R.id.tv_animal_rec)
        img_offline = findViewById(R.id.img_offline)
        tv_get_fail_remind = findViewById(R.id.tv_get_fail_remind)
        linAnimalGroup = findViewById(R.id.lin_animal_group)
        tvAnimalMute = findViewById(R.id.tv_animal_mute)
        tvAnimalVoice = findViewById(R.id.tv_animal_voice)
        tv_animal_catch = findViewById(R.id.tv_animal_catch)
        tv_animal_video = findViewById(R.id.tv_animal_video)
        img_back_logo = findViewById(R.id.img_back_logo)
        tv_animal_alarm = findViewById(R.id.tv_animal_alarm)
        lin_video_parent = findViewById(R.id.lin_video_parent)
        img_play = findViewById(R.id.img_play)
        tv_rec_time = findViewById(R.id.tv_rec_time)
        popUtils = PopUtils(this)


        initTitleView()


    }

    override fun initData() {
        val dm = resources.displayMetrics
        screenWidthDip = dm.widthPixels
        screenHeightDip = dm.heightPixels
        //初始化音频处理模块
        audioManager = getSystemService(AUDIO_SERVICE) as AudioManager
        current = audioManager!!.getStreamVolume(AudioManager.STREAM_MUSIC)
        audioManager!!.setStreamVolume(AudioManager.STREAM_MUSIC, current, 0)
        //当前处理设备的ID
        devId = intent.getStringExtra("devId")
        devType = intent.getIntExtra("devType", 0)
        //获取设备的详细信息
        if (!StringUtils.isEmpty(devId)) {
            val bdyList = getBuddyInfo()
            //读取影子设置
//            if (bdyList?.shaowStatus != null) {
//                cameraId = bdyList.shaowStatus!!.camera_id
//                isSupport264 = "H264" == bdyList.shaowStatus!!.video_f
//                power_mode = bdyList.shaowStatus!!.power_mode
//            }
            if (devType == BuddyType.TYPE_WIFI_DOOR_WS2) {
                isSupport264 = true
            }
        }
        //设置显示绘制界面
        surfaceviewVideo?.visibility = View.VISIBLE
        //设置画面旋转方向
        surfaceviewVideo?.rotation = equesMytool!!.getDegree(cameraId).toFloat()
        //设置显示比例
        setVideoSize()
        mCreateHolder = surfaceview?.holder
        mCreateHolder?.addCallback(this)
    }

    private var animationDrawable: AnimationDrawable? = null

    /**
     * 开始加载gif等待通话
     */
    private fun startLoadingAm() {
        if (ObjIsEmptyUtils.isEmpty(animationDrawable)) {
            animationDrawable = gf_videoLoadingGif?.drawable as AnimationDrawable
        }
        if (!ObjIsEmptyUtils.isEmpty(animationDrawable)) {
            animationDrawable!!.start()
        }
    }

    /**
     * 初始化头部标题栏
     */
    @SuppressLint("UseCompatLoadingForDrawables")
    private fun initTitleView() {
        tvMainLeftTopHint!!.visibility = View.VISIBLE
        tvMainLeftTopHint?.setCompoundDrawablesWithIntrinsicBounds(
            resources.getDrawable(R.mipmap.ic_invitation_menu), null, null, null
        )
        tvMainTitleHint!!.visibility = View.VISIBLE

        tvMainTitleHint!!.setTextColor(resources.getColor(R.color.black))
        tvMainLeftTopHint?.setOnClickListener {
            onBack()
        }
        ivMainRightTopHint?.visibility = View.VISIBLE
        ivMainRightTopHint?.setImageResource(R.mipmap.gray_set)
        ivMainRightTopHint?.setOnClickListener {
            //打开宠物设置界面
            var intent = Intent(ActionUtils.ACTION_COMMON_ANIMAL_SET_ACTIVITY)
            intent.putExtra(Config.BID, devId)
            intent.setPackage(packageName)
            intent.putExtra("devType", devType)
            startActivity(intent)
        }
    }

    /**
     * 设置宠物设备状态
     */
    private fun setState() {
        if (!isClick) {
            img_play?.visibility = View.VISIBLE
            img_offline?.visibility = View.GONE
            if (devState == Config.DEVICE_OFFLINE) {
                if (init) {
                    init = false
                    img_play?.visibility = View.GONE
                    img_offline?.visibility = View.VISIBLE
                    setSendFood(false)
                } else {
                    mHandler.postDelayed(Runnable {
                        getBuddyInfo()
                        if (!ObjIsEmptyUtils.isEmpty(devBean)) {
                            devState = devBean!!.stat
                            if (devState == Config.DEVICE_OFFLINE) {
                                img_play?.visibility = View.GONE
                                img_offline?.visibility = View.VISIBLE
                                setSendFood(false)
                            }
                        }
                    }, 3 * 1000)
                }
            }
        }
    }

    private fun getBuddyInfo() {
        CoroutineScope(Dispatchers.IO).launch {
            devBean = ykDao.getBdyListEntry(userName, devId!!)
        }
    }

    /**
     * 设置头部昵称
     */
    private fun setTitleNick() {
        ELog.d("setTitleNick", "devNick...$devNick")
        if (TextUtils.isEmpty(devNick)) {
            tvMainTitleHint!!.setText(R.string.animal)
        } else {
            tvMainTitleHint!!.text = devNick
        }
    }


    /**
     * 设置视频显示比例
     */
    private fun setVideoSize() {
        videoWidth = screenWidthDip.toFloat()
        videoHeight = videoWidth * 640f / 480f
//        videoHeight=screenHeightDip.toFloat()
        Log.e("width", "width...$screenHeightDip")
        var layoutParam = FrameLayout.LayoutParams(
            videoHeight.toInt(), videoWidth.toInt()
        )
        layoutParam.gravity = Gravity.CENTER_HORIZONTAL
        layoutParam.topMargin =
            ScreenUtils.dp2px(this, resources.getDimension(R.dimen.dp_20).toInt())
        surfaceviewVideo?.layoutParams = layoutParam

        var layoutParam2 = LinearLayout.LayoutParams(
            videoWidth.toInt(), videoHeight.toInt() + 50
        )
        lin_video_parent?.layoutParams = layoutParam2

        var layoutParam3 = LayoutParams(
            videoWidth.toInt(), videoHeight.toInt() + 50
        )
        img_back_logo?.layoutParams = layoutParam3
        var params = LayoutParams(
            LayoutParams.MATCH_PARENT, ScreenUtils.dp2px(this, 200)
        )
        params.addRule(RelativeLayout.ALIGN_PARENT_BOTTOM)
        linAnimalGroup?.layoutParams = params
    }

    /**
     * 获取设备详情
     */
    private fun getDeviceInfo() {
        ELog.d("buddyInfo is lockId...$devId")
        getBuddyInfo()
        if (!ObjIsEmptyUtils.isEmpty(devBean)) {
            uid = devBean!!.uid
            devType = devBean!!.role
            devNick = devBean!!.nick
            devState = devBean!!.stat
            devUpgradeStatus = devBean!!.remoteupg
            isShare = devBean!!.is_share
        } else {
            ELog.d("buddyInfo is null...")
        }
        setTitleNick()
        setState()
    }


    fun sendFood(value: Int) {
        setFood(value)
    }


    /**
     * 喂食 value 代表份数
     */
    private fun setFood(value: Int) {
        sendValue = value
        if (devState == Config.DEVICE_ONLINE) {
            showToast(getString(R.string.send_food_ing))
            mHandler.sendEmptyMessageDelayed(DISMISS_DIALOG, 25 * 1000)
            Log.e("FOOD", "send food 1")
            sendFoodValue()
        } else if (devState == Config.DEVICE_SLEEP) {
            showToast(getString(R.string.send_food_ing))
            isClickSendFood = true
            mHandler.sendEmptyMessageDelayed(DISMISS_DIALOG, 25 * 1000)
            wakeUp()
        } else {
            showToast(getString(R.string.bind_split_sleep))
        }
    }


    private fun sendFoodValue() {
        isClickSendFood = false
        DoorBellService.icvss!!.equesSendAnimalFood(devId, sendValue,-1)
        preference.putLong(devId + "send_food_time", System.currentTimeMillis())
    }


    /**
     * 进入呼叫位置 用于标识那个位置的调用了该方法
     */
    private fun call(position: Int) {
        // Log记录调用位置
        ELog.e("call", "METHOD $position call")
        // 当创建成功且未暂停时，尝试进行呼叫
        if (isCreateSuccess && !isPause) {
            // 发送加载中的消息
            mHandler.sendEmptyMessage(LOADING)
            // 发送加载超时消息，延迟25秒后执行
            mHandler.sendEmptyMessageDelayed(LOADING_TIME_OUT, 25 * 1000)
            // 显示加载中的视图
            linLoading?.visibility = View.VISIBLE
            // 启动加载动画
            startLoadingAm()
            // Log记录当前设备状态
            ELog.e("call", devState)
            // 根据设备状态执行相应的操作
            if (devState == Config.DEVICE_ONLINE) {
                // 如果设备在线，则直接进行呼叫
                call()
            } else if (devState == Config.DEVICE_SLEEP) {
                // 如果设备处于睡眠状态，则先唤醒设备
                wakeUp()
            } else {
                // 如果设备状态不是在线或睡眠，并且没有正在进行的呼叫
                if (!isHasCall) {
                    // 发送延迟加载视频的消息，延迟5秒后执行
                    mHandler.sendEmptyMessageDelayed(LOADING_DELAY_VIDEO, 5000)
                }
            }
        }
    }

    /**
     * 开始呼叫
     */
    private fun call() {
        // 检查是否已登录
        ELog.d("..." + DoorBellService.icvss!!.equesIsLogin())
        if (DoorBellService.icvss!!.equesIsLogin()) {
            // 如果尚未发起呼叫，则发起呼叫
            if (!isHasCall) {
                isHasCall = true
                // 调用IoT平台的呼叫方法
                DoorBellService.icvss!!.iot.call(
                    devType!!, uid, camera_width, camera_height, false, 0, 0, 0, 0
                )
            }
        } else {
            // 如果未登录，则设置呼叫状态为false并尝试登录
            isHasCall = false
            doorBellService!!.login(DoorBellService.MSG_ONCLICK_LOGIN)
        }
    }

    private fun wakeUp() {
        mHandler.sendEmptyMessage(REQUEST_AWAKEN)
    }


    @SuppressLint("SetTextI18n")
    private fun setPercent() {
        if (percent > 99) {
            percent = 99
        }
        tvLoading?.text = resources.getString(R.string.loading_safe) + " " + percent + "%"
    }

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_animal)
        ScreenUtils.unLockScreen(this@AnimalActivity)
        EventBus.getDefault().register(this@AnimalActivity)
        ykDao = BaseAppApplication.instance!!.getYkDao(this)
        preference.putBoolean("ring_call", false)
        userName = preference.getString(Config.EQUES_USER_NAME)!!
        path = FileHelper.getRootFilePath(this) + devId + ".jpg"
        Log.e("path", "$path 本地存储路径")

        initView()

        initData()

        isCreateOk = checkCapturePathIsExist()
    }

    @Subscribe(threadMode = ThreadMode.MAIN)
    fun onRefreshEvent(event: EventTotalThread) {
        when (event.refresh) {
            Config.EVENT_FINISH_ACTIVITY -> {
                finish()
            }

            Config.EVENT_METHOD_RMBDY_RESULT -> {
                val delResult: Boolean = event.isBooleanMsg!!
                if (delResult) {
                    finish()
                }
            }

            Config.CLIENT_AUTO_LOGIN_CONNECT_COMPLETE -> {
                ELog.d("onRefreshEvent", "用户登录成功")
                if (devState == Config.DEVICE_ONLINE && isClick) {
                    call(1)
                }
            }

            Config.EVENT_DEVICE_LIST_REFRESH -> {
                //列表刷新
                if (!StringUtils.isEmpty(devId)) {
                    if (devId.equals(event.stringMsg)) {
                        devState = event.intMsg
                    }
                    if (!videoIsPlaying) {
                        //当前视频没有接通过 设备睡眠了继续唤醒
                        if (devState == Config.DEVICE_ONLINE && isClick) {
                            mHandler.removeMessages(REQUEST_AWAKEN)
                            call(2)
                        }
                        setState()
                    }
                    if (devState == Config.DEVICE_ONLINE && isClickSendFood) {
                        sendFoodValue()
                    }
                }
            }

            234 -> {
                deviceOffline()
                closeAll(false, 2)
            }

            235 -> {
                // 设备通道建立 适配画面
                channelId = event.intMsg
                setDisplay()
            }

            Config.EVENT_REFRESH_SEND_FOOD_SUCCES -> {
                when (event.intMsg) {
                    0 -> {
                        isClickSendFood = false
                        stopProgressDialog()
                        ELog.showToast(
                            this, getString(R.string.animal_send_food_success), Toast.LENGTH_SHORT
                        )
                    }
                }

            }
        }
    }

    @SuppressLint("UseCompatLoadingForDrawables")
    private fun setButtonGray(enable: Boolean) {
        var drawableOne: Drawable
        var drawableTwo: Drawable
        var drawableThree: Drawable
        var drawableFour: Drawable
        if (enable) {
            drawableOne = resources.getDrawable(R.mipmap.animal_new_photo)
            drawableOne.setBounds(0, 0, drawableOne.minimumWidth, drawableOne.minimumHeight)

            drawableTwo = resources.getDrawable(R.mipmap.animal_phone_off)
            drawableTwo.setBounds(0, 0, drawableTwo.minimumWidth, drawableTwo.minimumHeight)

            drawableThree = resources.getDrawable(R.mipmap.animal_voice)
            drawableThree.setBounds(0, 0, drawableThree.minimumWidth, drawableThree.minimumHeight)

            drawableFour = resources.getDrawable(R.mipmap.animal_muteon)
            drawableFour.setBounds(0, 0, drawableFour.minimumWidth, drawableFour.minimumHeight)
        } else {
            drawableOne = resources.getDrawable(R.mipmap.photo_disabled_gray)
            drawableOne.setBounds(0, 0, drawableOne.minimumWidth, drawableOne.minimumHeight)

            drawableTwo = resources.getDrawable(R.mipmap.video_disabled_gray)
            drawableTwo.setBounds(0, 0, drawableTwo.minimumWidth, drawableTwo.minimumHeight)

            drawableThree = resources.getDrawable(R.mipmap.voice_disabled_gray)
            drawableThree.setBounds(0, 0, drawableThree.minimumWidth, drawableThree.minimumHeight)

            drawableFour = resources.getDrawable(R.mipmap.muteoff_gray)
            drawableFour.setBounds(0, 0, drawableFour.minimumWidth, drawableFour.minimumHeight)
        }
        tv_animal_catch?.isEnabled = enable
        tv_animal_catch?.setCompoundDrawables(null, drawableOne, null, null)

        tv_animal_video?.isEnabled = enable
        tv_animal_video?.setCompoundDrawables(null, drawableTwo, null, null)

        tvAnimalVoice?.isEnabled = enable
        tvAnimalVoice?.setCompoundDrawables(null, drawableThree, null, null)

        tvAnimalMute?.isEnabled = enable
        tvAnimalMute?.setCompoundDrawables(null, drawableFour, null, null)
    }


    @SuppressLint("UseCompatLoadingForDrawables")
    private fun setSendFood(enable: Boolean) {
        var drawable: Drawable
        var drawable2: Drawable
        if (enable) {
            drawable = resources.getDrawable(R.mipmap.animal_feed)
            drawable.setBounds(0, 0, drawable.minimumWidth, drawable.minimumHeight)

            drawable2 = resources.getDrawable(R.mipmap.feed_plan)
            drawable2.setBounds(0, 0, drawable2.minimumWidth, drawable2.minimumHeight)
        } else {
            drawable = resources.getDrawable(R.mipmap.feed_disabled_gray)
            drawable.setBounds(0, 0, drawable.minimumWidth, drawable.minimumHeight)

            drawable2 = resources.getDrawable(R.mipmap.feed_plan_disabled)
            drawable2.setBounds(0, 0, drawable2.minimumWidth, drawable2.minimumHeight)
        }
        tv_animal_send_food?.isEnabled = enable
        tv_animal_send_food?.setCompoundDrawables(null, drawable, null, null)

        tv_animal_clock?.isEnabled = enable
        tv_animal_clock?.setCompoundDrawables(null, drawable2, null, null)

    }

    private fun setDisplay() {
        DoorBellService.icvss!!.iot.setSurface(devType!!, channelId, mCreateHolder?.surface)
        mHandler.postDelayed(Runnable {
            DoorBellService.icvss!!.iot.audioRecordEnable(isRecordAudio)
            DoorBellService.icvss!!.iot.audioPlayEnable(isPlayAudio)
        }, 2000)

    }

    /**
     * 设备不在线
     */
    private fun deviceOffline() {
        rel_failed_video!!.visibility = View.VISIBLE
        linLoading?.visibility = View.GONE
        isClick = false
    }


    // 创建成功的SurfaceHolder对象
    private var mCreateHolder: SurfaceHolder? = null

    override fun onDestroy() {
        super.onDestroy()
        if (EventBus.getDefault().isRegistered(this@AnimalActivity)) {
            EventBus.getDefault().removeAllStickyEvents()
            EventBus.getDefault().unregister(this@AnimalActivity)
        }
        mCreateHolder?.removeCallback(this@AnimalActivity)
        closeSpeaker()
        closeAll(false, 1)
        if (surfaceThread != null) {
            surfaceThread?.isRunDraw = false
            if (surfaceThread?.isAlive == true) {
                surfaceThread?.interrupt()
            }
        }
        audioManager!!.setStreamMute(AudioManager.STREAM_MUSIC, false)
        current = audioManager!!.getStreamVolume(AudioManager.STREAM_MUSIC)
        audioManager!!.setStreamVolume(AudioManager.STREAM_MUSIC, current, 0)

    }


    /**
     * 关闭所有通话和视频播放相关资源
     *
     * @param isClose 布尔值，指示是否主动关闭通话或播放
     * @param number 整数，用于日志记录的额外信息，通常表示数量或顺序
     */
    private fun closeAll(isClose: Boolean, number: Int) {
        // 记录关闭操作的日志
        ELog.e(" closeAll()", " closeAll()......$number")
        // 设置视频播放和通话状态为false
        videoIsPlaying = false
        isHasCall = false
        // 重置点击状态
        isClick = false
        // 重置按钮状态，参数为false表示禁用按钮的灰色状态
        setButtonGray(false)
        // 移除消息队列中与长时间视频播放相关的消息
        mHandler.removeMessages(HANDLER_LONG_VIDEO_TIME)
        // 恢复默认的界面元素可见性
        img_back_logo?.visibility = View.VISIBLE
        img_play?.visibility = View.VISIBLE
        // 根据是否主动关闭，显示不同的提示信息
        if (isClose) {
            tv_get_fail_remind?.text = getString(R.string.video_limit_time)
        } else {
            tv_get_fail_remind?.text = getString(R.string.animal_get_video_failed)
        }
        // 停止录音功能
        stopRec(true)
        // 使用单线程执行器提交任务以异步方式关闭所有通话
        Executors.newSingleThreadExecutor().submit(Runnable {
            DoorBellService.icvss!!.iot.closeAllCall()
        })
    }

    override fun onKeyDown(keyCode: Int, event: KeyEvent): Boolean {
        when (keyCode) {
            KeyEvent.KEYCODE_BACK -> {
                if (event.repeatCount == 0) {
                    onBack()
                }
                return true
            }

            else -> {}
        }
        return super.onKeyDown(keyCode, event)
    }

    private fun onBack() {
        ELog.e("onBackPressed", "call_v2 $videoIsPlaying")
        if (videoIsPlaying) {
            closeAll(false, 5)
            createProgressDialog(this, R.string.exiting_please_wait, true)
            mHandler.sendEmptyMessageDelayed(
                HANDLER_MSG_CLOSE_CALL, TIME_CALL_CLOSE.toLong()
            )
        } else {
            finish()
        }
    }

    /**
     * 关闭扬声器
     */
    private fun closeSpeaker() {
        try {
            if (audioManager != null) {
                if (audioManager!!.isSpeakerphoneOn) {
                    audioManager!!.isSpeakerphoneOn = false
                }
            }
        } catch (e: java.lang.Exception) {
            e.printStackTrace()
        }
    }


    private fun setBack() {
        val bit = BitmapUtils.getDiskBitmap(path)
        if (!ObjIsEmptyUtils.isEmpty(bit)) {
            img_back_logo?.setImageBitmap(bit)
        }
    }

    override fun onResume() {
        isPause = false
        init = true
        setButtonGray(false)
        getDeviceInfo()
        setDeviceIsUpgrade()
        setBack()
        if (power_mode == 1 && leaveState) {
            call(11)
        }
        super.onResume()
    }

    override fun onPause() {
        mHandler.removeMessages(LOADING_TIME_OUT)
        isPause = true
        leaveState = videoIsPlaying
        closeAll(false, 4)
        super.onPause()
    }


    private var devUpgradeStatus = 0

    /**
     * 设置设备更新状态
     */
    private fun setDeviceIsUpgrade() {
        Log.e("Animal", "devUpgradeStatus...$devUpgradeStatus")
        //设备端升级标记
        var needUpdate = false
        if (devUpgradeStatus == 2) {
            //M1有新版本
            needUpdate = true
        }
        setNeedUpgradeTag(needUpdate)
    }


    /**
     * 是否可以升级标记
     */
    private fun setNeedUpgradeTag(isNeedUpgrade: Boolean) {
        if (isNeedUpgrade) {
            ivMainRightTopHint!!.setBackgroundResource(R.mipmap.gray_set_new)
        } else {
            ivMainRightTopHint!!.setBackgroundResource(R.mipmap.gray_set)
        }
    }

    override fun surfaceCreated(holder: SurfaceHolder) {
        if (surfaceThread == null) {
            surfaceThread = SurfaceThread()
        }
        doorBellService?.setImgDataListener(this)
        mCreateHolder = holder
        isCreateSuccess = true
    }


    override fun surfaceChanged(holder: SurfaceHolder, format: Int, width: Int, height: Int) {
        mCreateHolder = holder
    }

    override fun surfaceDestroyed(holder: SurfaceHolder) {
        mCreateHolder = holder

    }


    /**
     * 图片绘制线程
     */
    inner class SurfaceThread : Thread() {
        var isRunDraw = false
        override fun run() {
            super.run()
            while (isRunDraw) {
                if (!mjpeg!!.isDraw) {
                    if (isBitmapData) {
                        refreshBitmap(mjpeg!!.bitmap)
                    } else {
                        refreshSurface(mjpeg!!.bytes, mjpeg!!.len)
                    }
                    mjpeg!!.isDraw = true
                }
            }
        }
    }

    private var paint: Paint? = null
    private var canvas: Canvas? = null

    private fun refreshBitmap(bitmap: Bitmap) {
        var bitmap: Bitmap? = bitmap
        try {
            if (bitmap == null) {
                return
            }
            bitmap.setHasAlpha(true)
            catchBitmapToGalley(bitmap)
            canvas = surfaceviewVideo?.lockCanvas()
            val rectF = RectF(0f, 0f, videoHeight, videoWidth)
            if (canvas != null) {
                canvas!!.drawBitmap(bitmap, null, rectF, paint)
                surfaceviewVideo?.unlockCanvasAndPost(canvas!!)
                bitmap.recycle()
            }
        } catch (e: java.lang.Exception) {
            e.printStackTrace()
        }
    }


    /**
     * 开始刷新图片数据
     *
     * 此函数负责处理图片数据的更新和绘制它首先检查传入的字节数组是否有效，
     * 然后解码字节数组以创建位图对象，并将其绘制到画布上在绘制过程中，它还会进行错误处理和资源回收
     *
     * @param bytes 图片数据的字节数组，用于生成位图
     * @param len 表示字节数组中有效数据的长度
     */
    private fun refreshSurface(bytes: ByteArray?, len: Int) {
        // 确保传入的字节数组非空且长度合理
        if (bytes != null && bytes.isNotEmpty()) {
            var bitmap: Bitmap? = null
            try {
                // 如果指定长度大于字节数组长度，则不执行后续操作
                if (len > bytes.size) {
                    return
                }
                // 初始化画笔对象
                if (paint == null) {
                    paint = Paint() //画笔
                }
                // 设置画笔属性：抗锯齿、过滤位图、防止抖动
                paint!!.isAntiAlias = true //设置是否抗锯齿
                paint!!.isFilterBitmap = true
                paint!!.isDither = true // 防止抖动
                // 解码字节数组生成位图
                bitmap = BitmapFactory.decodeByteArray(bytes, 0, len)
                // 如果位图生成失败，终止后续操作
                if (bitmap == null) {
                    return
                }
                // 设置位图属性：具有透明度
                bitmap.setHasAlpha(true)
                // 将位图添加到画廊（假设这是一个自定义的方法用于处理位图）
                catchBitmapToGalley(bitmap)
                // 锁定画布以进行绘制
                canvas = surfaceviewVideo?.lockCanvas()
                // 定义绘制区域
                val rectF = RectF(0f, 0f, videoWidth, videoHeight)
                // 如果画布锁定成功，将位图绘制到画布上
                if (canvas != null) {
                    canvas!!.drawBitmap(bitmap, null, rectF, paint)
                    // 解锁画布并提交更改
                    surfaceviewVideo?.unlockCanvasAndPost(canvas!!)
                }
            } catch (e: Exception) {
                // 异常处理：打印异常信息
                e.printStackTrace()
            } finally {
                // 资源回收：回收位图资源
                bitmap?.recycle()
            }
        }
    }


    var isCatchOnePic = false

    /**
     * 抓拍图片去相册
     *
     * @param bitmap
     */
    private fun catchBitmapToGalley(bitmap: Bitmap) {
        if (!isCatchOnePic) {
            isCatchOnePic = true
            val matrix = Matrix()
            matrix.postRotate(equesMytool!!.getDegree(cameraId).toFloat())
            BitmapUtils.saveBmp3Gallery(
                Bitmap.createBitmap(
                    bitmap, 0, 0, bitmap.width, bitmap.height, matrix, true
                ), path
            )
        }
        if (isCatchBitmap) {
            isCatchBitmap = false
            val matrix = Matrix()
            matrix.postRotate(equesMytool!!.getDegree(cameraId).toFloat())
            mHandler.sendEmptyMessage(SAVE_PIC_TO_LOCAL)
            BitmapUtils.saveBmp3Gallery(
                this@AnimalActivity,
                Bitmap.createBitmap(bitmap, 0, 0, bitmap.width, bitmap.height, matrix, true),
                System.currentTimeMillis().toString() + "jpg"
            )
        }
    }


    override fun imgData(bytes: ByteArray?, len: Int) {
//        try {
        if (!videoIsPlaying) {
            mHandler.sendEmptyMessage(FIRST_FRAME_COME)
        }
        if (mjpeg == null) {
            mjpeg = Mjpeg(bytes, len, false)
        } else {
            mjpeg!!.bytes = bytes
            mjpeg!!.len = len
            mjpeg!!.isDraw = false
        }
        surfaceThread!!.isRunDraw = true
        if (!surfaceThread!!.isAlive) {
            if (!isStartThread) {
                isStartThread = true
                surfaceThread!!.start()
            }
        }
    }

    private var isBitmapData = false

    override fun bitmapData(data: Bitmap?) {
        isBitmapData = true
        if (!videoIsPlaying) {
            mHandler.sendEmptyMessage(FIRST_FRAME_COME)
        }
        if (mjpeg == null) {
            mjpeg = Mjpeg(false, data)
        } else {
            mjpeg!!.bitmap = data
            mjpeg!!.isDraw = false
        }
        surfaceThread!!.isRunDraw = true
    }


    override fun firFrameCome() {
        mHandler.sendEmptyMessage(FIRST_FRAME_COME)
    }
}